//
// Created by Martin on 2023/4/13.
//
#include "ftpserver/OsFile.h"

#define BOOST_TEST_MODULE OsFileTest
#define BOOST_TEST_MAIN
#define BOOST_TEST_DYN_LINK

#include <boost/test/unit_test.hpp>

using namespace std;
using namespace ftp::filesystem;

BOOST_AUTO_TEST_CASE(testOsFileReadLock)
{
    bool res(false);
    const char* path = "/dev/null";

    res = OSFileInstance.allocFile(path, kFileStatusRead);
    BOOST_TEST(res, true);
    OSFileInstance.freeFile(path);

    res = OSFileInstance.allocFile(path, kFileStatusRead);
    BOOST_CHECK_EQUAL(res, true);
    res = OSFileInstance.allocFile(path, kFileStatusRead);
    BOOST_CHECK_EQUAL(res, true);
    OSFileInstance.freeFile(path);
    OSFileInstance.freeFile(path);

    res = OSFileInstance.allocFile(path, kFileStatusRead);
    BOOST_CHECK_EQUAL(res, true);
    res = OSFileInstance.allocFile(path, kFileStatusRead);
    BOOST_CHECK_EQUAL(res, true);
    res = OSFileInstance.allocFile(path, kFileStatusRead);
    BOOST_CHECK_EQUAL(res, true);
    res = OSFileInstance.allocFile(path, kFileStatusRead);
    BOOST_CHECK_EQUAL(res, true);
    res = OSFileInstance.allocFile(path, kFileStatusRead);
    BOOST_CHECK_EQUAL(res, true);
    OSFileInstance.freeFile(path);
    OSFileInstance.freeFile(path);
    OSFileInstance.freeFile(path);
    OSFileInstance.freeFile(path);
    OSFileInstance.freeFile(path);
}

BOOST_AUTO_TEST_CASE(testOsFileWriteLock)
{
    bool res(false);
    const char* path = "/dev/null";

    res = OSFileInstance.allocFile(path, kFileStatusWrite);
    BOOST_CHECK_EQUAL(res, true);
    OSFileInstance.freeFile(path);

    res = OSFileInstance.allocFile(path, kFileStatusWrite);
    BOOST_CHECK_EQUAL(res, true);
    res = OSFileInstance.allocFile(path, kFileStatusWrite);
    BOOST_CHECK_EQUAL(res, false);
    OSFileInstance.freeFile(path);

    res = OSFileInstance.allocFile(path, kFileStatusWrite);
    BOOST_CHECK_EQUAL(res, true);
    res = OSFileInstance.allocFile(path, kFileStatusWrite);
    BOOST_CHECK_EQUAL(res, false);
    res = OSFileInstance.allocFile(path, kFileStatusWrite);
    BOOST_CHECK_EQUAL(res, false);
    res = OSFileInstance.allocFile(path, kFileStatusWrite);
    BOOST_CHECK_EQUAL(res, false);
    res = OSFileInstance.allocFile(path, kFileStatusWrite);
    BOOST_CHECK_EQUAL(res, false);
    OSFileInstance.freeFile(path);
}

BOOST_AUTO_TEST_CASE(testOsFileReadAndWriteLock)
{
    bool res(false);
    const char* path = "/dev/null";

    res = OSFileInstance.allocFile(path, kFileStatusRead);
    BOOST_CHECK_EQUAL(res, true);
    res = OSFileInstance.allocFile(path, kFileStatusWrite);
    BOOST_CHECK_EQUAL(res, false);
    OSFileInstance.freeFile(path);

    res = OSFileInstance.allocFile(path, kFileStatusRead);
    BOOST_CHECK_EQUAL(res, true);
    res = OSFileInstance.allocFile(path, kFileStatusWrite);
    BOOST_CHECK_EQUAL(res, false);
    res = OSFileInstance.allocFile(path, kFileStatusWrite);
    BOOST_CHECK_EQUAL(res, false);
    OSFileInstance.freeFile(path);

    res = OSFileInstance.allocFile(path, kFileStatusRead);
    BOOST_CHECK_EQUAL(res, true);
    res = OSFileInstance.allocFile(path, kFileStatusRead);
    BOOST_CHECK_EQUAL(res, true);
    res = OSFileInstance.allocFile(path, kFileStatusWrite);
    BOOST_CHECK_EQUAL(res, false);
    OSFileInstance.freeFile(path);
    OSFileInstance.freeFile(path);

    res = OSFileInstance.allocFile(path, kFileStatusRead);
    BOOST_CHECK_EQUAL(res, true);
    res = OSFileInstance.allocFile(path, kFileStatusWrite);
    BOOST_CHECK_EQUAL(res, false);
    res = OSFileInstance.allocFile(path, kFileStatusRead);
    BOOST_CHECK_EQUAL(res, true);
    OSFileInstance.freeFile(path);
    OSFileInstance.freeFile(path);
}

BOOST_AUTO_TEST_CASE(testOsFileWriteAndReadLock)
{
    bool res(false);
    const char *path = "/dev/null";

    res = OSFileInstance.allocFile(path, kFileStatusWrite);
    BOOST_CHECK_EQUAL(res, true);
    res = OSFileInstance.allocFile(path, kFileStatusRead);
    BOOST_CHECK_EQUAL(res, false);
    OSFileInstance.freeFile(path);

    res = OSFileInstance.allocFile(path, kFileStatusWrite);
    BOOST_CHECK_EQUAL(res, true);
    res = OSFileInstance.allocFile(path, kFileStatusRead);
    BOOST_CHECK_EQUAL(res, false);
    res = OSFileInstance.allocFile(path, kFileStatusRead);
    BOOST_CHECK_EQUAL(res, false);
    OSFileInstance.freeFile(path);
}
